package com.jason.data.controller;

import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSDownloadStream;
import com.mongodb.client.gridfs.model.GridFSFile;
import lombok.extern.slf4j.Slf4j;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.gridfs.GridFsResource;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;

/**
 * 参照： https://blog.csdn.net/qq_31960623/article/details/121950896
 */
@RestController
@Slf4j
public class TfileController {

    @Autowired
    GridFsTemplate gridFsTemplate;

    @Autowired
    GridFSBucket gridFSBucket;


    @PostMapping("/upload")
    public Object upload(MultipartFile file) throws IOException {

        //文件名称
        String filename = file.getOriginalFilename();

        //文件输入流
        InputStream inputStream = file.getInputStream();

        //文件类型
        String contentType = file.getContentType();

        //上传文件中使用BasicDBObject添加一些属性
        DBObject metaDate = new BasicDBObject();
        metaDate.put("key", "hello mongodb");

        //MongoDB存储图片、视频
        ObjectId id = gridFsTemplate.store(inputStream, filename, contentType, metaDate);
        log.debug("文件id:{}", id);
        return id.toString();
    }

    @GetMapping("/getFile")
    public Object getFile(@RequestParam("id") String fileId, @RequestParam("name") String name) {

        Query query = new Query();
        Criteria id = Criteria.where("_id").is(fileId);
        Criteria filename1 = Criteria.where("filename").is(name);
//        Criteria criteria = new Criteria().orOperator(id, filename1);
        query.addCriteria(new Criteria().orOperator(Criteria.where("filename").is(name),Criteria.where("filename").is(name)));

        //查找文件(图片、视频等)信息
        GridFSFile gridFSFile = gridFsTemplate.findOne(query);
         if (gridFSFile == null) {

            return "文件不存在";
        }
        String filename = gridFSFile.getFilename();
        log.debug("文件名称：{}", filename);
        Object meta = gridFSFile.getMetadata().get("key");
        log.debug("meta属性值：{}", meta);
        return gridFSFile.toString();
    }

    //下载文件
    @GetMapping("/download")
    public void download(@RequestParam("id") String fileId, @RequestParam("name") String name, HttpServletResponse response) throws IOException {

        Query query = new Query();
        query.addCriteria(new Criteria().orOperator(Criteria.where("_id").is(fileId),Criteria.where("filename").is(name)));
        GridFSFile gridFSFile = gridFsTemplate.findOne(query);
        if (gridFSFile == null) {
            //文件不存在
            log.debug("文件不存在，id:{}", fileId);
            return;
        }
        //解决中文乱码
        String fileName = new String(gridFSFile.getFilename().getBytes("GBK"), "ISO-8859-1");

        response.addHeader("Content-Disposition", "attachment;filename=" + fileName);


        GridFSDownloadStream gridFSDownloadStream = gridFSBucket.openDownloadStream(gridFSFile.getObjectId());

        //创建GridFsResource，获取流对象
        GridFsResource resource = new GridFsResource(gridFSFile, gridFSDownloadStream);

        InputStream inputStream = resource.getInputStream();
        ServletOutputStream outputStream = response.getOutputStream();
        byte[] bytes = new byte[1024];
        int len;
        while ((len = inputStream.read(bytes)) != -1) {
            outputStream.write(bytes, 0, len);
        }

        inputStream.close();
    }

    //删除文件
    @GetMapping("/delFile")
    public void delFile(@RequestParam("id") String fileId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(fileId));
        GridFSFile gridFSFile = gridFsTemplate.findOne(query);
        if (gridFSFile == null) {
            //文件不存在
            log.debug("文件不存在，id:{}", fileId);
            return;
        }
        ObjectId objectId = gridFSFile.getObjectId();
        gridFsTemplate.delete(query);
        log.debug("文件删除成功,文件id:{}", fileId);
    }
}
